{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Eigenvalues and Eigenvectors\n",
    "\n",
    "Multiplication by a matrix is a linear tansformation that maps vectors (points) to different vectors(points).\n",
    "\n",
    "But in special cases,  vectors will not change (except for scaling) when transformed.\n",
    "\n",
    "An eigen vector $\\vec{e}$ for a linear transformation represented by matrix $A$ will satisfy $A\\vec{e} = \\lambda \\vec{e}$.\n",
    "\n",
    "In other words, $A$ maps its eigenvector $\\vec{e}$ to (a scaled version) of itself."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eigen values are\n",
      "tensor([0.7071+0.7071j, 0.7071-0.7071j, 1.0000+0.0000j])\n",
      "\n",
      "Eigen vectors are\n",
      "tensor([[0.7071+0.0000j, 0.0000+0.7071j, 0.0000+0.0000j],\n",
      "        [0.7071-0.0000j, 0.0000-0.7071j, 0.0000-0.0000j],\n",
      "        [0.0000+0.0000j, 0.0000+0.0000j, 1.0000+0.0000j]])\n",
      "\n",
      "Note that 1 + 0j i.e 1 is an Eigen value\n",
      "and [0, 0, 1+0j] i.e Z Axis is an Eigen vector.\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "from torch import linalg as LA\n",
    "\n",
    "# A = [cos(45)  sin(45)  0]\n",
    "#     [-sin(45) cos(45)  0]\n",
    "#     [0              0  1]\n",
    "# This matrix performs a rotation about the Z axis [0  0  1].\n",
    "# All rotation matrices have 1 as an eigen-value. The corresponding\n",
    "# eigenvector will be the axis of rotation.\n",
    "# This is consistent with the physical definition of rotation axis -\n",
    "# that points on the axis stay where they were post the rotation.\n",
    "A = torch.tensor([[0.7071, 0.7071, 0], [-0.7071, 0.7071, 0], [0, 0, 1]])\n",
    "\n",
    "# LA.eig returns eigen values in the array l and the corresponding\n",
    "# eigen vectors as columns of e.\n",
    "# Note that eigen values can be complex numbers (with a real and\n",
    "# imaginary part). The imaginary part will be expressed via\n",
    "# j which denotes square root of -1 (imaginary number).\n",
    "l, e = LA.eig(A)\n",
    "\n",
    "print(\"Eigen values are\\n{}\\n\".format(l)) \n",
    "print(\"Eigen vectors are\\n{}\\n\\n\"\n",
    "      \"Note that 1 + 0j i.e 1 is an Eigen value\\n\"\n",
    "      \"and [0, 0, 1+0j] i.e Z Axis is an Eigen vector.\".format(e.T))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
